﻿using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
using System.Threading;

namespace NetworkLibrary
{

    internal class Request
    {
        public ushort SessionId { get; init; }
        public Response Response { get; set; }
    }
    internal class Response
    {
        public ushort Code;
        public IMessage Result;
    }

    public struct Result<T> where T : IMessage
    {
        public int Code { get; init; }
        public T Message { get; init; }
    }


    public class LocalProcedureCallService : IAsyncProcedureCall, ISyncProcedureCall
    {
        public Task<Result<TResponse>> Call<TRequest, TResponse>(TRequest message)
            where TRequest : IMessage
            where TResponse : IMessage
        {
            throw new System.NotImplementedException();
        }

        public Task Call<TRequest>(TRequest message) where TRequest : IMessage
        {
            throw new System.NotImplementedException();
        }

        Result<TResponse> ISyncProcedureCall.Call<TRequest, TResponse>(TRequest message)
        {
            throw new System.NotImplementedException();
        }

        void ISyncProcedureCall.Call<TRequest>(TRequest message)
        {
            throw new System.NotImplementedException();
        }
    }

    public abstract class RemoteService : IProcedureCallService
    {
        private IProcedureCallService _local;
        private IndexSet<Request> _requests;
        public RemoteService()
        {
            _requests = new IndexSet<Request>(32);
        }
        protected void OnResponse(ushort sessionId, ushort code, IMessage message)
        {
            var request = _requests.Pop(sessionId);
            var response = new Response() { Code = code, Result = message };
            request.Response = response;
        }
        protected void OnRequest(ushort type, ushort sessionId, IMessage message)
        {

        }

        protected abstract void Response(ushort sessionId, ushort code, IMessage message);

        public async Task<(ushort Code, IMessage Result)> Request(ushort type, IMessage message)
        {
            throw new System.NotImplementedException();
        }
    }
}
